/*
 * jxController Project (2014)
 * 
 * by Denilson Edinaldo Pinto
 * 
 * LGPL
 * Copyright (C) 2014
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
package org.jxController.view;

import java.awt.Component;
import java.awt.ComponentOrientation;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.Set;

import javax.swing.AbstractButton;
import javax.swing.ImageIcon;
import javax.swing.JComboBox;
import javax.swing.JFormattedTextField;
import javax.swing.JOptionPane;
import javax.swing.JSpinner;
import javax.swing.JToolBar;
import javax.swing.JTree;
import javax.swing.text.JTextComponent;
import javax.swing.tree.TreeModel;

import org.jxController.event.CrudEvent;
import org.jxSwing.Cleanable;
import org.jxSwing.component.JXComponent;
import org.jxSwing.component.button.DeleteButton;
import org.jxSwing.component.button.EditButton;
import org.jxSwing.component.button.NewButton;
import org.jxSwing.component.button.PrintButton;
import org.jxSwing.component.button.RefreshButton;
import org.jxSwing.component.button.SaveButton;
import org.jxSwing.component.button.SearchButton;
import org.jxSwing.component.button.UndoButton;
import org.jxSwing.component.panel.BeanTablePanel;
import org.jxSwing.component.panel.ImageCustomPanel;
import org.jxSwing.component.panel.ImagePanel;
import org.jxSwing.component.panel.ImageScrollPanel;
import org.jxSwing.component.table.BeanTable;
import org.jxSwing.component.text.NumberField;
import org.jxSwing.i18n.I18N;
import org.jxUtils.check.CheckUtil;
import org.jxUtils.lang.StringAsync;

/**
 * @author Denilson Edinaldo Pinto
 * @porject jxController
 * @package org.jxController.view
 * @date 03/05/2014 - 10:31:01
 */
public final class CrudBar extends JToolBar {
	
	private static final long serialVersionUID = -6017765722115119452L;
	
	private static final CrudBar CRUD_BAR = new CrudBar();
	
	/**
	 * btnSearch = [0]<br>
	 * btnNew = [1]<br>
	 * btnEdit = [2]<br>
	 * btnSave = [3]<br>
	 * btnUndo = [4]<br>
	 * btnDelete = [5]<br>
	 * btnPrint = [6]<br>
	 */
	private final Boolean[] lastState = new Boolean[7];
	
	/**
	 * canSearch = [0]<br>
	 * canInclude = [1]<br>
	 * canEdit = [2]<br>
	 * canDelete = [3]<br>
	 * canPrint = [4]<br>
	 */
	private final Boolean[] permissions = new Boolean[5];
	
	private final Set<FieldAux> fields = new LinkedHashSet<>();
	
	private boolean showTextInCrudButtons = false;
	
	private boolean isNew = false;
	
	private CrudEvent crudEvent;
	
	private Component owner;
	
	private RefreshButton btnRefresh;
	
	private SearchButton btnSearch;
	
	private NewButton btnNew;
	
	private EditButton btnEdit;
	
	private SaveButton btnSave;
	
	private UndoButton btnUndo;
	
	private DeleteButton btnDelete;
	
	private PrintButton btnPrint;
	
	/**
	 *
	 */
	public CrudBar() {
	
		this(null, true, true, true, true, true);
	}
	
	/**
	 * @param owner
	 */
	public CrudBar(final Component owner) {
	
		this(owner, true, true, true, true, true);
	}
	
	/**
	 * @param owner
	 * @param canSearch
	 * @param canInclude
	 * @param canEdit
	 * @param canDelete
	 * @param canPrint
	 */
	public CrudBar(final Component owner, final boolean canSearch, final boolean canInclude, final boolean canEdit, final boolean canDelete, final boolean canPrint) {
	
		permissions[0] = canSearch;
		permissions[1] = canInclude;
		permissions[2] = canEdit;
		permissions[3] = canDelete;
		permissions[4] = canPrint;
		
		initGUI();
		
		setOwner(owner);
	}
	
	/**
	 * @param owner
	 * @param lock
	 * @param fields
	 */
	private static void lockOwnerFields(final Component owner, final boolean lock, final Set<FieldAux> fields) {
	
		//
		if(owner instanceof Container) {
			
			//
			for(final Component component : ((Container)owner).getComponents()) {
				
				//
				if(isField(component)) {
					
					component.setEnabled( !lock);
					
					String name = component.getName();
					
					//
					if(CheckUtil.isNullOrAbsoluteEmpty(name)) {
						
						name = component.getClass().getSimpleName() + " in [" + component.getX() + ", " + component.getY() + "]";
					}
					
					//
					Object initialValue = null;
					
					//
					if(component instanceof JFormattedTextField) {
						
						final JFormattedTextField formattedTextField = (JFormattedTextField)component;
						
						initialValue = formattedTextField.getValue();
						
						//
						if( !formattedTextField.isEditable()) {
							
							formattedTextField.setEnabled(true);
						}
						
					}else if(component instanceof JTextComponent) {
						
						final JTextComponent textComponent = (JTextComponent)component;
						
						initialValue = textComponent.getText();
						
						//
						if( !textComponent.isEditable()) {
							
							textComponent.setEnabled(true);
						}
						
					}else if(component instanceof JComboBox) {
						
						final JComboBox<?> comboBox = (JComboBox<?>)component;
						
						initialValue = comboBox.getSelectedItem();
						
					}else if(component instanceof JTree) {
						
						final JTree tree = (JTree)component;
						
						initialValue = tree.getModel();
						
					}else if(component instanceof BeanTable) {
						
						final BeanTable<?> table = (BeanTable<?>)component;
						
						initialValue = table.getRows();
						
					}else if(component instanceof BeanTablePanel) {
						
						final BeanTablePanel<?> tablePanel = (BeanTablePanel<?>)component;
						
						tablePanel.setEnabledCrudButtons( !lock);
						
						initialValue = tablePanel.getRows();
						
					}else if(component instanceof ImagePanel) {
						
						ImagePanel imagePanel = (ImagePanel)component;
						
						initialValue = imagePanel.getImage();
						
					}else if(component instanceof ImageCustomPanel) {
						
						ImageCustomPanel imagePanel = (ImageCustomPanel)component;
						
						initialValue = imagePanel.getImage();
						
					}else if(component instanceof ImageScrollPanel) {
						
						ImageScrollPanel imagePanel = (ImageScrollPanel)component;
						
						initialValue = imagePanel.getImage();
					}
					
					//
					fields.add(CRUD_BAR.new FieldAux(name, component, initialValue));
					
				}else {
					
					lockOwnerFields(component, lock, fields);
				}
			}
		}
	}
	
	/**
	 * 
	 */
	private void setButtonsSize() {
	
		int width = getHeight();
		
		Font font = getBtnRefresh().getFont();
		
		// 
		if(isShowTextInCrudButtons()) {
			
			int visibleButtons = 0;
			
			visibleButtons += getBtnRefresh().isVisible() ? 1 : 0;
			visibleButtons += getBtnSearch().isVisible() ? 1 : 0;
			visibleButtons += getBtnNew().isVisible() ? 1 : 0;
			visibleButtons += getBtnEdit().isVisible() ? 1 : 0;
			visibleButtons += getBtnSave().isVisible() ? 1 : 0;
			visibleButtons += getBtnUndo().isVisible() ? 1 : 0;
			visibleButtons += getBtnDelete().isVisible() ? 1 : 0;
			visibleButtons += getBtnPrint().isVisible() ? 1 : 0;
			
			width = getWidth() / visibleButtons;
			
			width = width <= 80 ? width : 80;
			
			font = new Font(font.getName(), Font.PLAIN, font.getSize());
		}
		
		getBtnRefresh().setSize(width, getHeight());
		getBtnSearch().setSize(width, getHeight());
		getBtnNew().setSize(width, getHeight());
		getBtnEdit().setSize(width, getHeight());
		getBtnSave().setSize(width, getHeight());
		getBtnUndo().setSize(width, getHeight());
		getBtnDelete().setSize(width, getHeight());
		getBtnPrint().setSize(width, getHeight());
		
		getBtnRefresh().setFont(font);
		getBtnSearch().setFont(font);
		getBtnNew().setFont(font);
		getBtnEdit().setFont(font);
		getBtnSave().setFont(font);
		getBtnUndo().setFont(font);
		getBtnDelete().setFont(font);
		getBtnPrint().setFont(font);
	}
	
	/**
	 * @param component
	 * @return true if the param component is a type {@link JTextComponent} or {@link AbstractButton} or {@link JComboBox} or {@link JSpinner} or {@link JTree} or {@link BeanTable} or {@link BeanTablePanel}
	 */
	protected static boolean isField(final Component component) {
	
		return component instanceof JTextComponent || 
			component instanceof AbstractButton || 
			component instanceof JComboBox || 
			component instanceof JSpinner || 
			component instanceof JTree || 
			component instanceof BeanTable || 
			component instanceof BeanTablePanel || 
			component instanceof ImagePanel || 
			component instanceof ImageCustomPanel;
	}
	
	/**
	 * @param showMessage
	 * @param fields
	 */
	public static final boolean requiredFieldsAreFilled(final boolean showMessage, final Set<FieldAux> fields) {
	
		Component firstFieldNotFilled = null;
		
		final StringAsync fieldsNotFilled = new StringAsync();
		
		boolean isNotFilled = false;
		
		//
		for(final FieldAux fieldAux : fields) {
			
			final Component component = fieldAux.getComponent();
			
			isNotFilled = false;
			
			//
			if(component instanceof JXComponent) {
				
				final JXComponent jxComponent = (JXComponent)component;
				
				//
				if(jxComponent.isRequired()) {
					
					//
					if(component instanceof JFormattedTextField) {
						
						final JFormattedTextField formattedTextField = (JFormattedTextField)component;
						
						isNotFilled = CheckUtil.isNull(formattedTextField.getValue()) || CheckUtil.isAbsoluteEmpty(formattedTextField.getValue().toString());
						
					}else if(component instanceof JTextComponent) {
						
						isNotFilled = CheckUtil.isAbsoluteEmpty(((JTextComponent)component).getText());
						
					}else if(component instanceof JComboBox) {
						
						isNotFilled = CheckUtil.isNullOrEmpty(((JComboBox<?>)component).getSelectedItem());
						
					}else if(component instanceof JTree) {
						
						final TreeModel model = ((JTree)component).getModel();
						
						isNotFilled = CheckUtil.isNull(model) || CheckUtil.isNull(model.getRoot());
						
					}else if(component instanceof BeanTable) {
						
						isNotFilled = ((BeanTable<?>)component).isEmpty();
						
					}else if(component instanceof BeanTablePanel) {
						
						isNotFilled = ((BeanTablePanel<?>)component).isEmpty();
						
					}else if(component instanceof ImagePanel) {
						
						isNotFilled = ((ImagePanel)component).getImage() != null;
						
					}else if(component instanceof ImageCustomPanel) {
						
						isNotFilled = ((ImageCustomPanel)component).getImage() != null;
						
					}else if(component instanceof ImageScrollPanel) {
						
						isNotFilled = ((ImageScrollPanel)component).getImage() != null;
					}
				}
				
				//
				if(isNotFilled) {
					
					//
					if(firstFieldNotFilled == null) {
						
						firstFieldNotFilled = component;
					}
					
					//
					fieldsNotFilled.append(I18N.component().notFilledField(fieldAux.getName()));
					fieldsNotFilled.appendLine();
				}
			}
		}
		
		//
		if(fieldsNotFilled.isEmpty()) {
			
			return true;
			
		}else {
			
			//
			if(showMessage) {
				
				JOptionPane.showMessageDialog(null, fieldsNotFilled, I18N.component().fillRequiredFields(), JOptionPane.WARNING_MESSAGE);
			}
			
			firstFieldNotFilled.requestFocusInWindow();
			
			return false;
		}
	}
	
	/**
	 * @param owner
	 * @param showMessage
	 */
	public static final boolean requiredFieldsAreFilled(final Component owner, final boolean showMessage) {
		
		final Set<FieldAux> fields = new LinkedHashSet<>();
		
		lockOwnerFields(owner, false, fields);
		
		return requiredFieldsAreFilled(showMessage, fields);
	}
	
	private void initGUI() {
	
		setSize(250, 45);
		setFloatable(false);
		setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
		
		add(getBtnPrint());
		add(getBtnDelete());
		add(getBtnUndo());
		add(getBtnSave());
		add(getBtnEdit());
		add(getBtnNew());
		add(getBtnSearch());
		add(getBtnRefresh());
		
		addComponentListener(new ComponentAdapter() {
			
			@Override
			public void componentResized(final ComponentEvent componentEvent) {

				setButtonsSize();
			}
		});
		
		enableDisableButtons(true, true, false, false, false, false, true);
	}
	
	/**
	 *
	 */
	protected boolean requiredFieldsAreFilled() {
	
		return requiredFieldsAreFilled(true);
	}
	
	/**
	 *
	 */
	public final void applyLastState() {

		getBtnRefresh().setEnabled(lastState[5]);
		getBtnSearch().setEnabled(lastState[0]);
		getBtnNew().setEnabled(lastState[1]);
		getBtnEdit().setEnabled(lastState[2]);
		getBtnSave().setEnabled(lastState[3]);
		getBtnUndo().setEnabled(lastState[4]);
		getBtnDelete().setEnabled(lastState[5]);
		getBtnPrint().setEnabled(lastState[6]);
	}
	
	/**
	 *
	 */
	public final void clearFields() {
	
		//
		for(final FieldAux fieldAux : fields) {
			
			final Component component = fieldAux.getComponent();
			
			//
			if(component instanceof Cleanable) {
				
				((Cleanable)component).clear();
				
			}else if(component instanceof JFormattedTextField) {
				
				((JFormattedTextField)component).setValue(null);
				
			}else if(component instanceof JTextComponent) {
				
				((JTextComponent)component).setText("");
				
			}else if(component instanceof AbstractButton) {
				
				((AbstractButton)component).setSelected(false);
				
			}else if(component instanceof JComboBox) {
				
				((JComboBox<?>)component).setSelectedItem(0);
				
			}else if(component instanceof JSpinner) {
				
				((JSpinner)component).setValue(null);
				
			}else if(component instanceof JTree) {
				
				((JTree)component).setModel((TreeModel)fieldAux.getInitialValue());
				
			}else if(component instanceof ImagePanel) {
				
				((ImagePanel)component).setImage((ImageIcon)null);
				
			}else if(component instanceof ImageCustomPanel) {
				
				((ImageCustomPanel)component).setImage((ImageIcon)null);
				
			}else if(component instanceof ImageScrollPanel) {
				
				((ImageScrollPanel)component).setImage((ImageIcon)null);
			}
		}
	}
	
	/**
	 * @param search
	 * @param include
	 * @param edit
	 * @param save
	 * @param undo
	 * @param delete
	 * @param print
	 */
	public final void enableDisableButtons(final boolean search, final boolean include, final boolean edit, final boolean save, final boolean undo, final boolean delete, final boolean print) {
	
		lastState[0] = permissions[0] && search;
		lastState[1] = permissions[1] && include;
		lastState[2] = permissions[2] && edit;
		lastState[3] = save;
		lastState[4] = undo;
		lastState[5] = permissions[3] && delete;
		lastState[6] = permissions[4] && print;
		
		applyLastState();
	}
	
	public final DeleteButton getBtnDelete() {
	
		if(btnDelete == null) {
			btnDelete = new DeleteButton();
			btnDelete.addActionListener(new ActionListener() {
				
				@Override
				public void actionPerformed(final ActionEvent actionEvent) {
				
					isNew = false;
					
					//
					if(getCrudEvent() != null && getCrudEvent().deleteAction()) {
						
						clearFields();
						lockOwnerFields(true);
						enableDisableButtons(true, true, false, false, false, false, true);
						getBtnNew().requestFocusInWindow();
					}
				}
			});
		}
		return btnDelete;
	}
	
	public final EditButton getBtnEdit() {
	
		if(btnEdit == null) {
			btnEdit = new EditButton();
			btnEdit.addActionListener(new ActionListener() {
				
				@Override
				public void actionPerformed(final ActionEvent actionEvent) {
				
					isNew = false;
					
					lockOwnerFields(false);
					enableDisableButtons(false, false, false, true, true, false, false);
					
					//
					if(getCrudEvent() != null) {
						
						getCrudEvent().editAction();
					}
				}
			});
		}
		return btnEdit;
	}
	
	public final NewButton getBtnNew() {
	
		if(btnNew == null) {
			btnNew = new NewButton();
			btnNew.addActionListener(new ActionListener() {
				
				@Override
				public void actionPerformed(final ActionEvent actionEvent) {
				
					isNew = true;
					
					clearFields();
					lockOwnerFields(false);
					enableDisableButtons(false, false, false, true, true, false, false);
					
					//
					if(getCrudEvent() != null) {
						
						getCrudEvent().newAction();
					}
				}
			});
		}
		return btnNew;
	}
	
	public final PrintButton getBtnPrint() {
	
		if(btnPrint == null) {
			btnPrint = new PrintButton();
			btnPrint.addActionListener(new ActionListener() {
				
				@Override
				public void actionPerformed(final ActionEvent actionEvent) {
				
					isNew = false;
					
					//
					if(getCrudEvent() != null) {
						
						getCrudEvent().printAction();
					}
				}
			});
		}
		return btnPrint;
	}
	
	public final RefreshButton getBtnRefresh() {
	
		if(btnRefresh == null) {
			btnRefresh = new RefreshButton();
			btnRefresh.setEnabled(false);
			btnRefresh.setVisible(false);
			btnRefresh.addActionListener(new ActionListener() {
				
				@Override
				public void actionPerformed(final ActionEvent actionEvent) {
				
					//
					if(getCrudEvent() != null) {
						
						isNew = false;
						
						getCrudEvent().refreshAction();
					}
				}
			});
		}
		return btnRefresh;
	}
	
	public final SaveButton getBtnSave() {
	
		if(btnSave == null) {
			btnSave = new SaveButton();
			btnSave.addActionListener(new ActionListener() {
				
				@Override
				public void actionPerformed(final ActionEvent actionEvent) {
				
					//
					if(requiredFieldsAreFilled()) {
						
						isNew = false;
						
						//
						if(getCrudEvent() != null && getCrudEvent().saveAction()) {
							
							lockOwnerFields(true);
							enableDisableButtons(true, true, true, false, false, true, true);
							getBtnNew().requestFocusInWindow();
						}
					}
				}
			});
		}
		return btnSave;
	}
	
	public final SearchButton getBtnSearch() {
	
		if(btnSearch == null) {
			btnSearch = new SearchButton();
			btnSearch.addActionListener(new ActionListener() {
				
				@Override
				public void actionPerformed(final ActionEvent actionEvent) {
				
					isNew = false;
					
					//
					if(getCrudEvent() != null && getCrudEvent().findAction() || requiredFieldsAreFilled(false)) {
						
						enableDisableButtons(true, true, true, false, false, true, true);
						
					}else {
						
						enableDisableButtons(true, true, false, false, false, false, true);
						
						getBtnNew().requestFocusInWindow();
					}
				}
			});
		}
		return btnSearch;
	}
	
	public final UndoButton getBtnUndo() {
	
		if(btnUndo == null) {
			btnUndo = new UndoButton();
			btnUndo.addActionListener(new ActionListener() {
				
				@Override
				public void actionPerformed(final ActionEvent actionEvent) {
				
					lockOwnerFields(true);
					
					//
					if(isNew) {
						
						enableDisableButtons(true, true, false, false, false, false, true);
						
					}else {
						
						enableDisableButtons(true, true, true, false, false, true, true);
					}
					
					//
					if(getCrudEvent() != null) {
						
						getCrudEvent().undoAction();
						
					}else {
						
						clearFields();
					}
					
					getBtnEdit().requestFocusInWindow();
					
					isNew = false;
				}
			});
		}
		return btnUndo;
	}
	
	/**
	 * @return the crudEvent
	 */
	public CrudEvent getCrudEvent() {
	
		return crudEvent;
	}

	/**
	 * @return {@code getBtnRefresh().isVisible()}
	 */
	public boolean isShowRefreshButton() {
	
		return getBtnRefresh().isVisible();
	}
	
	/**
	 * @return the showTextInCrudButtons
	 */
	public boolean isShowTextInCrudButtons() {
	
		return showTextInCrudButtons;
	}
	
	/**
	 *
	 */
	public final void lock() {
	
		saveLastState();

		getBtnRefresh().setEnabled(false);
		getBtnSearch().setEnabled(false);
		getBtnNew().setEnabled(false);
		getBtnEdit().setEnabled(false);
		getBtnSave().setEnabled(false);
		getBtnUndo().setEnabled(false);
		getBtnDelete().setEnabled(false);
		getBtnPrint().setEnabled(false);
	}
	
	/**
	 * @param lock
	 */
	public final void lockOwnerFields(final boolean lock) {
	
		lockOwnerFields(owner, lock, fields);
	}
	
	/**
	 * @param showMessage
	 */
	public final boolean requiredFieldsAreFilled(final boolean showMessage) {
		
		return requiredFieldsAreFilled(showMessage, fields);
	}
	
	/**
	 *
	 */
	@SuppressWarnings("unchecked")
	public final void restoreFieldsValues() {
	
		//
		for(final FieldAux fieldAux : fields) {
			
			final Component component = fieldAux.getComponent();
			
			//
			if(component instanceof JFormattedTextField) {
				
				final JFormattedTextField textField = (JFormattedTextField)component;
				
				textField.setValue(fieldAux.getInitialValue());
				
			}else if(component instanceof NumberField) {
				
				final NumberField numberField = (NumberField)component;
				
				numberField.setText((String)fieldAux.getInitialValue());
				
			}else if(component instanceof JTextComponent) {
				
				final JTextComponent textField = (JTextComponent)component;
				
				textField.setText((String)fieldAux.getInitialValue());
				
			}else if(component instanceof AbstractButton) {
				
				((AbstractButton)component).setSelected(fieldAux.getInitialValue() != null ? (boolean)fieldAux.getInitialValue() : false);
				
			}else if(component instanceof JComboBox) {
				
				final JComboBox<?> comboBox = (JComboBox<?>)component;
				
				comboBox.setSelectedItem(fieldAux.getInitialValue());
				
			}else if(component instanceof JSpinner) {
				
				((JSpinner)component).setValue(fieldAux.getInitialValue());
				
			}else if(component instanceof JTree) {
				
				final JTree tree = (JTree)component;
				
				tree.setModel((TreeModel)fieldAux.getInitialValue());
				
			}else if(component instanceof BeanTable) {
				
				final BeanTable<Object> table = (BeanTable<Object>)component;
				
				table.setRows((Collection<Object>)fieldAux.getInitialValue());
				
			}else if(component instanceof BeanTablePanel) {
				
				final BeanTablePanel<Object> tablePanel = (BeanTablePanel<Object>)component;
				
				tablePanel.setRows((Collection<Object>)fieldAux.getInitialValue());
				
			}else if(component instanceof ImagePanel) {
				
				((ImagePanel)component).setImage((ImageIcon)fieldAux.getInitialValue());
				
			}else if(component instanceof ImageCustomPanel) {
				
				((ImageCustomPanel)component).setImage((ImageIcon)fieldAux.getInitialValue());
				
			}else if(component instanceof ImageScrollPanel) {
				
				((ImageScrollPanel)component).setImage((ImageIcon)fieldAux.getInitialValue());
			}
		}
	}
	
	/**
	 *
	 */
	public final void saveLastState() {
	
		lastState[0] = getBtnSearch().isEnabled();
		lastState[1] = getBtnNew().isEnabled();
		lastState[2] = getBtnEdit().isEnabled();
		lastState[3] = getBtnSave().isEnabled();
		lastState[4] = getBtnUndo().isEnabled();
		lastState[5] = getBtnDelete().isEnabled();
		lastState[6] = getBtnPrint().isEnabled();
	}
	
	/**
	 * @param crudEvent
	 *        the crudEvent to set
	 */
	public void setCrudEvent(final CrudEvent crudEvent) {
	
		this.crudEvent = crudEvent;
	}
	
	/**
	 * @param owner
	 */
	public final void setOwner(final Component owner) {
	
		this.owner = owner;
		
		//
		if(owner != null) {
			
			lockOwnerFields(true);
		}
	}
	
	/**
	 * @param canSearch
	 * @param canInclude
	 * @param canEdit
	 * @param canDelete
	 * @param canPrint
	 */
	public final void setPermissions(final boolean canSearch, final boolean canInclude, final boolean canEdit, final boolean canDelete, final boolean canPrint) {
	
		permissions[0] = canSearch;
		permissions[1] = canInclude;
		permissions[2] = canEdit;
		permissions[3] = canDelete;
		permissions[4] = canPrint;
		
		enableDisableButtons(true, true, false, false, false, false, true);
	}
	
	/**
	 * @param showRefreshButton
	 */
	public final void showRefreshButton(boolean showRefreshButton) {
	
		getBtnRefresh().setVisible(showRefreshButton);
	}
	
	/**
	 * @param showTextInCrudButtons
	 */
	public final void showTextInCrudButtons(boolean showTextInCrudButtons) {
		
		this.showTextInCrudButtons = showTextInCrudButtons;
		
		// 
		if(isShowTextInCrudButtons()) {
			
			setPreferredSize(new Dimension(250, 55));
			
		}else {
			
			setPreferredSize(new Dimension(250, 45));
		}
		
		//
		getBtnRefresh().setText(isShowTextInCrudButtons() ? getBtnRefresh().getToolTipText() : null);
		getBtnRefresh().setHorizontalTextPosition(isShowTextInCrudButtons() ? CENTER : TRAILING);
		getBtnRefresh().setVerticalTextPosition(isShowTextInCrudButtons() ? BOTTOM : CENTER);
		getBtnRefresh().setIconTextGap(isShowTextInCrudButtons() ? 0 : 4);
		
		getBtnSearch().setText(isShowTextInCrudButtons() ? getBtnSearch().getToolTipText() : null);
		getBtnSearch().setHorizontalTextPosition(isShowTextInCrudButtons() ? CENTER : TRAILING);
		getBtnSearch().setVerticalTextPosition(isShowTextInCrudButtons() ? BOTTOM : CENTER);
		getBtnSearch().setIconTextGap(isShowTextInCrudButtons() ? 0 : 4);
		
		getBtnNew().setText(isShowTextInCrudButtons() ? getBtnNew().getToolTipText() : null);
		getBtnNew().setHorizontalTextPosition(isShowTextInCrudButtons() ? CENTER : TRAILING);
		getBtnNew().setVerticalTextPosition(isShowTextInCrudButtons() ? BOTTOM : CENTER);
		getBtnNew().setIconTextGap(isShowTextInCrudButtons() ? 0 : 4);
		
		getBtnEdit().setText(isShowTextInCrudButtons() ? getBtnEdit().getToolTipText() : null);
		getBtnEdit().setHorizontalTextPosition(isShowTextInCrudButtons() ? CENTER : TRAILING);
		getBtnEdit().setVerticalTextPosition(isShowTextInCrudButtons() ? BOTTOM : CENTER);
		getBtnEdit().setIconTextGap(isShowTextInCrudButtons() ? 0 : 4);
		
		getBtnSave().setText(isShowTextInCrudButtons() ? getBtnSave().getToolTipText() : null);
		getBtnSave().setHorizontalTextPosition(isShowTextInCrudButtons() ? CENTER : TRAILING);
		getBtnSave().setVerticalTextPosition(isShowTextInCrudButtons() ? BOTTOM : CENTER);
		getBtnSave().setIconTextGap(isShowTextInCrudButtons() ? 0 : 4);
		
		getBtnUndo().setText(isShowTextInCrudButtons() ? getBtnUndo().getToolTipText() : null);
		getBtnUndo().setHorizontalTextPosition(isShowTextInCrudButtons() ? CENTER : TRAILING);
		getBtnUndo().setVerticalTextPosition(isShowTextInCrudButtons() ? BOTTOM : CENTER);
		getBtnUndo().setIconTextGap(isShowTextInCrudButtons() ? 0 : 4);
		
		getBtnDelete().setText(isShowTextInCrudButtons() ? getBtnDelete().getToolTipText() : null);
		getBtnDelete().setHorizontalTextPosition(isShowTextInCrudButtons() ? CENTER : TRAILING);
		getBtnDelete().setVerticalTextPosition(isShowTextInCrudButtons() ? BOTTOM : CENTER);
		getBtnDelete().setIconTextGap(isShowTextInCrudButtons() ? 0 : 4);
		
		getBtnPrint().setText(isShowTextInCrudButtons() ? getBtnPrint().getToolTipText() : null);
		getBtnPrint().setHorizontalTextPosition(isShowTextInCrudButtons() ? CENTER : TRAILING);
		getBtnPrint().setVerticalTextPosition(isShowTextInCrudButtons() ? BOTTOM : CENTER);
		getBtnPrint().setIconTextGap(isShowTextInCrudButtons() ? 0 : 4);
		
		//
		setButtonsSize();
	}

	/**
	 *
	 */
	public final void unlock() {
	
		applyLastState();
	}
	
	/**
	 * @author Denilson Edinaldo Pinto
	 * @porject jxController
	 * @package org.jxController.view
	 * @date 12/05/2014 - 21:23:29
	 */
	private final class FieldAux {
		
		private final String name;
		
		private final Component component;
		
		private final Object initialValue;
		
		/**
		 * @param name
		 * @param component
		 * @param initialValue
		 */
		public FieldAux(final String name, final Component component, final Object initialValue) {
		
			this.name = name;
			this.component = component;
			this.initialValue = initialValue;
		}
		
		private CrudBar getOuterType() {
		
			return CrudBar.this;
		}
		
		/*
		 * (non-Javadoc)
		 * 
		 * @see java.lang.Object#equals(java.lang.Object)
		 */
		@Override
		public boolean equals(final Object obj) {
		
			if(this == obj) {
				return true;
			}
			if(obj == null) {
				return false;
			}
			if( !(obj instanceof FieldAux)) {
				return false;
			}
			final FieldAux other = (FieldAux)obj;
			if( !getOuterType().equals(other.getOuterType())) {
				return false;
			}
			if(component == null) {
				if(other.component != null) {
					return false;
				}
			}else if( !component.equals(other.component)) {
				return false;
			}
			if(name == null) {
				if(other.name != null) {
					return false;
				}
			}else if( !name.equals(other.name)) {
				return false;
			}
			return true;
		}
		
		/**
		 * @return the component
		 */
		public final Component getComponent() {
		
			return component;
		}
		
		/**
		 * @return the initialValue
		 */
		public final Object getInitialValue() {
		
			return initialValue;
		}
		
		/**
		 * @return the name
		 */
		public final String getName() {
		
			return name;
		}
		
		/*
		 * (non-Javadoc)
		 * 
		 * @see java.lang.Object#hashCode()
		 */
		@Override
		public int hashCode() {
		
			final int prime = 31;
			int result = 1;
			result = prime * result + getOuterType().hashCode();
			result = prime * result + (component == null ? 0 : component.hashCode());
			result = prime * result + (name == null ? 0 : name.hashCode());
			return result;
		}
		
		/*
		 * (non-Javadoc)
		 * 
		 * @see java.lang.Object#toString()
		 */
		@Override
		public String toString() {
		
			return (name != null ? name + ", " : "") + (component != null ? component + ", " : "") + (initialValue != null ? initialValue : "");
		}
	}
}
